goog.provide('dkpoints.tests');

goog.require('soy');
goog.require('goog.json');

goog.require('dkpoints.rpc');
goog.require('dkpoints.utils');
goog.require('dkpoints.tests.templates');
goog.require('dkpoints.rpc.commands.GetTierList');

/**
 * Values against which to check test results
 * type {Object}
 */
dkpoints.tests.constants = {};

/**
 * Expected tier list.
 * @type {Array}
 * @const
 */
dkpoints.tests.constants.tierListArray = ["7.0", "8.0", "9.0", "9.5", "10.0", "10.5"];

/**
 * The kick-off function for testing.
 */
dkpoints.tests.init = function() {
  dkpoints.utils.loadCSS("tests");
  
  /* These tests need to happen in sequence, so each test calls the others in order */
  
  // Begin the GetTierList command object test chain.
  dkpoints.tests.getTierListTest1();
};

/**
 * Mark a test as done.
 * @param {string} testID The ID of the test to mark.
 * @param {boolean} pass Whether the test passed or failed.
 */
dkpoints.tests.markTestDone = function(testID, pass) {
  pass = pass ? "pass" : "fail";
  goog.dom.$(testID + 'Header').appendChild(soy.renderAsFragment(dkpoints.tests.templates.markComplete, {result: pass}));
};

/**
 * Run the first GetTierList command object test.
 */
dkpoints.tests.getTierListTest1 = function() {
  var me = dkpoints.tests,
      profileStart = Date.now(),
      body = goog.dom.$('body_content');
  
  var testID = "GetTierList1";
  
  var rpc = dkpoints.rpc;
  
  var testParams = {
    testName: "Command Object Tests: GetTierList - Test 1",
    testDesc: "Create a dkpoints.rpc.commands.GetTierList object to retrieve the tier list.  No instance tier requested.",
    panelID: testID
  }
  
  var frag = soy.renderAsFragment(dkpoints.tests.templates.testCase, testParams);
  
  body.appendChild(frag);
  var testPanel = goog.dom.$(testID);
  
  /* Clear the RPC cache */
  var cacheClear = soy.renderAsFragment(dkpoints.tests.templates.setupStep, { setupDesc: "Clearing the RPC cache."} );
  testPanel.appendChild(cacheClear);
  
  rpc.clearCache();
  
  /* Create the command object and give it to the RPC service. */
  var cmd = new rpc.commands.GetTierList(goog.partial(me.getTierListTest1Callback, testPanel, profileStart));
  
  rpc.execute(cmd);
};

/**
 * Got the response from the GetTierList command object.
 * @param {HTMLDivElement} testPanel The div for this test
 * @param {number} profileStart The Date.now() when this process was started
 * @param {!Object} cmdResponse The response from the command.
 */
dkpoints.tests.getTierListTest1Callback = function(testPanel, profileStart, cmdResponse) {
  var me = dkpoints.tests,
      templates = dkpoints.tests.templates;
  
  var testPass = true,
      actualList = cmdResponse.tierList,
      actualLen = actualList.length,
      
      expectedList = me.constants.tierListArray,
      expectedLen = expectedList.length;

  if(actualLen !== expectedLen) {
    testPass = false;
  }
  
  for(var i = actualLen; i-- && testPass; ) {
    if(actualList[i] !== expectedList[i]) {
      testPass = false;
    }
  }
  
  var resultFrag = null;
  if(testPass) {
    resultFrag = soy.renderAsFragment(templates.positiveResult, {resultString: "Retrieved tier list matched expected tier list."});
  }
  else {
    resultFrag = soy.renderAsFragment(templates.negativeResult, {resultString: "Retrieved tier list did not match expected tier list."});
  }
  
  var details = {
    posOrNeg: testPass ? "positive" : "negative",
    details: [
      {
        resultTitle: "Expected List",
        resultDetail: goog.json.serialize(expectedList)
      },
      {
        resultTitle: "Returned Result",
        resultDetail: goog.json.serialize(actualList)
      }
    ]
  };
  
  resultFrag.appendChild(
    soy.renderAsFragment(templates.resultDetails, details)
  );
  
  // Print profile results.
  var profileResults = "Test completed in " + (Date.now() - profileStart) + "ms.";
  testPanel.appendChild( soy.renderAsFragment(templates.profileResults, {profileResults: profileResults}) );
  
  // Print test results.
  testPanel.appendChild(resultFrag);
  me.markTestDone("GetTierList1", testPass);
  
  // Set up a timeout so that control can return to the RPC in order to
  // allow it to cache the response.
  setTimeout(me.getTierListTest2, 25);
};

/**
 * Run the first GetTierList command object test.
 */
dkpoints.tests.getTierListTest2 = function() {
  var me = dkpoints.tests,
      profileStart = Date.now(),
      body = goog.dom.$('body_content'),
      templates = dkpoints.tests.templates;
  
  var testID = "GetTierList2",
      testPass = true,
      testParams = {
        testName: "Command Object Tests: GetTierList - Test 2",
        testDesc: "Check that the TierList was cached after Test 1.",
        panelID: testID
      };
  
  var frag = soy.renderAsFragment(dkpoints.tests.templates.testCase, testParams);
  
  body.appendChild(frag);
  var testPanel = goog.dom.$(testID);
  
  /* Get the RPC cache and check to see if a TierList is in there. */
  var cache = dkpoints.rpc.getCacheForTest(),
      tierList = (! goog.isNull(cache)) ? cache.getCacheData("TierList") : undefined,
      resultFrag = null; // Document fragment to hold the results.
  
  if(! goog.isDef(tierList)) {
    // No tier list was cached.
    
    testPass = false;
    resultFrag = soy.renderAsFragment(templates.negativeResult,
      {resultString: "TierList was not cached."}
    );
  }
  else {
    resultFrag = soy.renderAsFragment(templates.positiveResult,
      {resultString: "TierList was cached."}
    );
  }
  
  if(testPass) {
    // Yep, there's a tier list.  Does it match what we expected?
    
    var actualList = tierList.getData(),
        actualLen = actualList.length,
        
        expectedList = me.constants.tierListArray,
        expectedLen = expectedList.length;
    
    if(actualLen !== expectedLen) {
      testPass = false;
    }
    
    for(var i = actualLen; i-- && testPass; ) {
      if(actualList[i] !== expectedList[i]) {
        testPass = false;
      }
    }
    
    if(testPass) {
      resultFrag.appendChild(soy.renderAsFragment(templates.positiveResult, {resultString: "Retrieved tier list matched expected tier list."}));
    }
    else {
      resultFrag.appendChild(soy.renderAsFragment(templates.negativeResult, {resultString: "Retrieved tier list did not match expected tier list."}));
    }
    
    var details = {
      posOrNeg: testPass ? "positive" : "negative",
      details: [
        {
          resultTitle: "Expected List",
          resultDetail: goog.json.serialize(expectedList)
        },
        {
          resultTitle: "Returned Result",
          resultDetail: goog.json.serialize(actualList)
        }
      ]
    };
    
    resultFrag.appendChild(
      soy.renderAsFragment(templates.resultDetails, details)
    );
  }
  
  // Print profile results.
  var profileResults = "Test completed in " + (Date.now() - profileStart) + "ms.";
  testPanel.appendChild( soy.renderAsFragment(templates.profileResults, {profileResults: profileResults}) );
  
  // Print test results.
  testPanel.appendChild(resultFrag);
  me.markTestDone("GetTierList2", testPass);
};